package tijava.generics;

import java.util.ArrayList;
import java.util.List;

public class TestGenerics {
	@SuppressWarnings("unused")
	public static void main(String[] args) {
		// WARNING: GenericFoo is a raw type. References to generic type
		// GenericFoo<T> should be parameterized
		GenericFoo gf = new GenericFoo(new Fruit());

		// OK:
		GenericFoo<Fruit> cli = new GenericFoo<Fruit>(new Fruit());

		// ERROR: Type mismatch: cannot convert from GenericFoo<Apple> to
		// GenericFoo<Fruit>
		// GenericFoo<Fruit> cli2 = new GenericFoo<Apple>(new Apple());

		// OK:
		GenericFoo<? extends Fruit> cli3 = new GenericFoo<Apple>(new Apple());

		// ERROR: The method setX(capture#3-of ? extends Fruit) in the type
		// GenericFoo<capture#3-of ? extends Fruit> is not applicable for the
		// arguments (Apple)
		// cli3.setX(new Apple());

		// OK:
		GenericFoo<?> cli4 = new GenericFoo<Apple>(new Apple());

		// ERROR: The method setX(capture#3-of ?) in the type
		// GenericFoo<capture#3-of ?> is not applicable for the arguments
		// (Apple)
		// cli4.setX(new Apple());

		// OK:
		GenericFoo<? super Apple> cli5 = new GenericFoo<Fruit>(new Fruit());

		// ERROR: Type mismatch: cannot convert from GenericFoo<Jonathan> to
		// GenericFoo<? super Apple>
		// GenericFoo<? super Apple> cli6 = new GenericFoo<Jonathan>(new
		// Fruit());

		// ERROR: Bound mismatch: The type TestGenerics is not a valid
		// substitute for the bounded parameter <T extends Fruit> of the type
		// GenericFoo<T>
		// GenericFoo<TestGenerics> cli = new GenericFoo<TestGenerics>(new
		// Fruit());

		// OK:
		Number[] n = new Integer[3];
		n[0] = 1; // OK:

		// Runtime Exception: Exception in thread "main"
		// java.lang.ArrayStoreException: java.lang.Double
		// n[1] = 1.1;

		// OK:
		List<Number> ln = new ArrayList<Number>();
		ln.add(1); // OK:
		ln.add(1.1); // OK:

		List<Integer> li = new ArrayList<Integer>();

		// ERROR: Type mismatch: cannot convert from List<Integer> to
		// List<Number>
		// ln = li;

		// ERROR: Type mismatch: cannot convert from ArrayList<Integer> to
		// List<Number>
		// List<Number> ln2 = new ArrayList<Integer>();

		// ERROR: Cannot create a generic array of ArrayList<String>
		// List<String>[] lsa = new ArrayList<String>[3];

		// ERROR: Syntax error on token "int", Dimensions expected after this
		// token
		// List<int> li = new ArrayList<int>();
	}
}
